package club.kynb.mall.application.flow.order;

import club.kynb.mall.application.context.OrderPreviewContext;
import club.kynb.mall.application.model.model.dto.PreviewOrderDTO;
import club.kynb.mall.application.model.model.dto.UserReceiveCouponDTO;
import club.kynb.mall.application.model.model.vo.OrderPreviewResultVO;
import club.kynb.mall.order.model.dto.ShoppingCartDTO;
import cn.hutool.core.util.NumberUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.pizza.pattern.filter.Filter;
import org.pizza.pattern.filter.FilterInvoker;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

/**
 * @author kynb_club@163.com
 * @since 2021/7/5 9:02 下午
 */
@Slf4j
@Component
@AllArgsConstructor
public class CalculatePreviewAmountFilter implements Filter<OrderPreviewContext> {
    @Override
    public void doFilter(OrderPreviewContext orderPreviewContext, FilterInvoker<OrderPreviewContext> filterInvoker) {
        log.info("计算金额过滤器 start");
        this.calculateTotalItemNum(orderPreviewContext);
        this.calculateTotalAmount(orderPreviewContext);
        this.calculateFreightAmount(orderPreviewContext);
        this.calculateCouponAmount(orderPreviewContext);
        this.calculateDiscountAmount(orderPreviewContext);
        this.calculatePayableAmount(orderPreviewContext);
        this.calculatePayAmount(orderPreviewContext);
        log.info("计算金额过滤器 end");
        filterInvoker.invoke(orderPreviewContext);
    }

    private void calculateTotalItemNum(OrderPreviewContext orderPreviewContext) {
        final int sum = orderPreviewContext.getCheckedList().stream().mapToInt(ShoppingCartDTO::getSkuNum).sum();
        final PreviewOrderDTO previewOrderDTO = orderPreviewContext.getOrderPreviewResultVO().getPreviewOrderDTO();
        previewOrderDTO.setTotalItemNum(sum);
    }

    private void calculateTotalAmount(OrderPreviewContext orderPreviewContext) {
        final PreviewOrderDTO previewOrderDTO = orderPreviewContext.getOrderPreviewResultVO().getPreviewOrderDTO();
        //商品总价格
        previewOrderDTO
                .setTotalAmount(orderPreviewContext.calculateTotalAmount(orderPreviewContext.getFilteredSpuList(), orderPreviewContext.getCheckedList()));
    }

    private void calculateFreightAmount(OrderPreviewContext orderPreviewContext) {
        final PreviewOrderDTO previewOrderDTO = orderPreviewContext.getOrderPreviewResultVO().getPreviewOrderDTO();
        previewOrderDTO
                .setFreightAmount(BigDecimal.ZERO);
    }

    private void calculateCouponAmount(OrderPreviewContext orderPreviewContext) {
        final OrderPreviewResultVO orderPreviewResultVO = orderPreviewContext.getOrderPreviewResultVO();
        final PreviewOrderDTO previewOrderDTO = orderPreviewResultVO.getPreviewOrderDTO();
        final UserReceiveCouponDTO recommendCoupon = orderPreviewResultVO.getRecommendCoupon();
        if (recommendCoupon == null) {
            previewOrderDTO.setCouponAmount(BigDecimal.ZERO);
        } else {
            previewOrderDTO.setCouponAmount(new BigDecimal(recommendCoupon.getCouponValue()));
        }
    }

    private void calculateDiscountAmount(OrderPreviewContext orderPreviewContext) {
        final OrderPreviewResultVO orderPreviewResultVO = orderPreviewContext.getOrderPreviewResultVO();
        final PreviewOrderDTO previewOrderDTO = orderPreviewResultVO.getPreviewOrderDTO();
        //优惠总金额（优惠券总金额+其他优惠金额）
        previewOrderDTO.setDiscountAmount(previewOrderDTO.getCouponAmount());
    }

    private void calculatePayableAmount(OrderPreviewContext orderPreviewContext) {
        final OrderPreviewResultVO orderPreviewResultVO = orderPreviewContext.getOrderPreviewResultVO();
        final PreviewOrderDTO previewOrderDTO = orderPreviewResultVO.getPreviewOrderDTO();
        //应付金额（商品总价+运费）
        previewOrderDTO.setPayableAmount(NumberUtil.add(previewOrderDTO.getTotalAmount(), previewOrderDTO.getFreightAmount()));
    }

    private void calculatePayAmount(OrderPreviewContext orderPreviewContext) {
        final OrderPreviewResultVO orderPreviewResultVO = orderPreviewContext.getOrderPreviewResultVO();
        final PreviewOrderDTO previewOrderDTO = orderPreviewResultVO.getPreviewOrderDTO();
        //实付金额（商品总价+运费-优惠总金额）
        previewOrderDTO.setPayAmount(NumberUtil.sub(previewOrderDTO.getPayableAmount(), previewOrderDTO.getDiscountAmount()));
    }


}
